{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz\n",
      "17465344/17464789 [==============================] - 3s 0us/step\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "<__array_function__ internals>:5: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\keras\\datasets\\imdb.py:159: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray\n",
      "  x_train, y_train = np.array(xs[:idx]), np.array(labels[:idx])\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\keras\\datasets\\imdb.py:160: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray\n",
      "  x_test, y_test = np.array(xs[idx:]), np.array(labels[idx:])\n"
     ]
    }
   ],
   "source": [
    "from keras.datasets import imdb\n",
    "(train_data,train_labels),(test_data,test_labels) = imdb.load_data(num_words=8000) #前8000个单词(每局评论至多包含8000个单词)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "shape of train data is  (25000,)\n",
      "shape of train labels is  (25000,)\n",
      "an example of train data is  [1, 778, 128, 74, 12, 630, 163, 15, 4, 1766, 7982, 1051, 2, 32, 85, 156, 45, 40, 148, 139, 121, 664, 665, 10, 10, 1361, 173, 4, 749, 2, 16, 3804, 8, 4, 226, 65, 12, 43, 127, 24, 2, 10, 10]\n"
     ]
    }
   ],
   "source": [
    "print('shape of train data is ',train_data.shape)\n",
    "print('shape of train labels is ',train_labels.shape)\n",
    "print('an example of train data is ',train_data[5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 神经网络的输入必须是tensor而不是list，所以需要将数据集处理为25000*8000\n",
    "def vectorize_sequences(sequences,dimension=8000):\n",
    "    # 生成25000*8000的二维Numpy数组\n",
    "    results = np.zeros((len(sequences),dimension))\n",
    "    # one-hot编码\n",
    "    for i,sequence in enumerate(sequences):\n",
    "        results[i,sequence] = 1.\n",
    "    return results\n",
    "x_train = vectorize_sequences(train_data)\n",
    "x_test = vectorize_sequences(test_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 1., 1., ..., 0., 0., 0.],\n",
       "       [0., 1., 1., ..., 0., 0., 0.],\n",
       "       [0., 1., 1., ..., 0., 0., 0.],\n",
       "       ...,\n",
       "       [0., 1., 1., ..., 0., 0., 0.],\n",
       "       [0., 1., 1., ..., 0., 0., 0.],\n",
       "       [0., 1., 1., ..., 0., 0., 0.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 0, 0, ..., 0, 1, 0], dtype=int64)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = np.asarray(train_labels).astype('float32')\n",
    "y_test = np.asarray(test_labels).astype('float32')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras import models\n",
    "from keras import layers\n",
    "def build_model():\n",
    "    model = models.Sequential()\n",
    "    model.add(layers.Dense(16,activation='relu',input_shape=(8000,)))\n",
    "    model.add(layers.Dense(16,activation='relu'))\n",
    "    model.add(layers.Dense(1,activation='sigmoid'))\n",
    "    model.compile(optimizer='rmsprop',# 还可以通过optimizer = optimizers.RMSprop(lr=0.001)来为优化器指定参数\n",
    "                  loss='binary_crossentropy', # 等价于loss = losses.binary_crossentropy\n",
    "                  metrics=['accuracy']) # 等价于metrics = [metircs.binary_accuracy]\n",
    "    return model\n",
    "model = build_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_val = x_train[:10000]\n",
    "partial_x_train = x_train[10000:]\n",
    "y_val = y_train[:10000]\n",
    "partial_y_train = y_train[10000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
      "30/30 [==============================] - 3s 63ms/step - loss: 0.5986 - accuracy: 0.6926 - val_loss: 0.3987 - val_accuracy: 0.8643\n",
      "Epoch 2/20\n",
      "30/30 [==============================] - 1s 31ms/step - loss: 0.3339 - accuracy: 0.8990 - val_loss: 0.3330 - val_accuracy: 0.8699\n",
      "Epoch 3/20\n",
      "30/30 [==============================] - 1s 32ms/step - loss: 0.2435 - accuracy: 0.9229 - val_loss: 0.2892 - val_accuracy: 0.8867\n",
      "Epoch 4/20\n",
      "30/30 [==============================] - 1s 31ms/step - loss: 0.1951 - accuracy: 0.9346 - val_loss: 0.2774 - val_accuracy: 0.8893\n",
      "Epoch 5/20\n",
      "30/30 [==============================] - 1s 32ms/step - loss: 0.1613 - accuracy: 0.9487 - val_loss: 0.2790 - val_accuracy: 0.8868\n",
      "Epoch 6/20\n",
      "30/30 [==============================] - 1s 31ms/step - loss: 0.1343 - accuracy: 0.9587 - val_loss: 0.2872 - val_accuracy: 0.8862\n",
      "Epoch 7/20\n",
      "30/30 [==============================] - 1s 33ms/step - loss: 0.1158 - accuracy: 0.9649 - val_loss: 0.3046 - val_accuracy: 0.8849\n",
      "Epoch 8/20\n",
      "30/30 [==============================] - 1s 32ms/step - loss: 0.0946 - accuracy: 0.9736 - val_loss: 0.3180 - val_accuracy: 0.8824\n",
      "Epoch 9/20\n",
      "30/30 [==============================] - 1s 32ms/step - loss: 0.0860 - accuracy: 0.9761 - val_loss: 0.3393 - val_accuracy: 0.8762\n",
      "Epoch 10/20\n",
      "30/30 [==============================] - 1s 34ms/step - loss: 0.0731 - accuracy: 0.9800 - val_loss: 0.3617 - val_accuracy: 0.8759\n",
      "Epoch 11/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0653 - accuracy: 0.9821 - val_loss: 0.3956 - val_accuracy: 0.8706\n",
      "Epoch 12/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0541 - accuracy: 0.9869 - val_loss: 0.4078 - val_accuracy: 0.8737\n",
      "Epoch 13/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0442 - accuracy: 0.9903 - val_loss: 0.4363 - val_accuracy: 0.8716\n",
      "Epoch 14/20\n",
      "30/30 [==============================] - 1s 34ms/step - loss: 0.0374 - accuracy: 0.9924 - val_loss: 0.4644 - val_accuracy: 0.8688\n",
      "Epoch 15/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0323 - accuracy: 0.9933 - val_loss: 0.4904 - val_accuracy: 0.8696\n",
      "Epoch 16/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0310 - accuracy: 0.9932 - val_loss: 0.5199 - val_accuracy: 0.8675\n",
      "Epoch 17/20\n",
      "30/30 [==============================] - 1s 35ms/step - loss: 0.0225 - accuracy: 0.9965 - val_loss: 0.5873 - val_accuracy: 0.8623\n",
      "Epoch 18/20\n",
      "30/30 [==============================] - 1s 36ms/step - loss: 0.0210 - accuracy: 0.9968 - val_loss: 0.6031 - val_accuracy: 0.8638\n",
      "Epoch 19/20\n",
      "30/30 [==============================] - 1s 36ms/step - loss: 0.0173 - accuracy: 0.9974 - val_loss: 0.6118 - val_accuracy: 0.8643\n",
      "Epoch 20/20\n",
      "30/30 [==============================] - 1s 34ms/step - loss: 0.0126 - accuracy: 0.9990 - val_loss: 0.6459 - val_accuracy: 0.8633\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(partial_x_train,\n",
    "                    partial_y_train,\n",
    "                    epochs=20, # 在全数据集上迭代20次\n",
    "                    batch_size=512, # 每个batch的大小为512\n",
    "                    validation_data=(x_val,y_val))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "history_dict = history.history\n",
    "history_dict.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'dict_keys' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-12-20b0fb772edb>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdict_keys\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'val_loss'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'val_acc'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'loss'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'acc'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'dict_keys' is not defined"
     ]
    }
   ],
   "source": [
    "dict_keys(['val_loss', 'val_acc', 'loss', 'acc'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x23d41fec9d0>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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b2XixImVCb9Emq5assWPP8Lrr8NVV4VxRUceGQaY7rNP6OUzf36oChoxAk4/PRyTSUkA4i0RLAUOTnjeHFhWwjGr3P174Hszmwx0BOYlHuTuo4HREMYRxBbxburfvz9jx47l5JNP3r5t7Nix3HXXXRV6/YQJE3b7vceNG8cZZ5xB27ZtAbj99tt3+1wi2WLtWnj55fCtf8IEWLMG6taFk0+G228PN/ymTZMdZc2JM69NBVqbWUsz2xO4ABhf7JjngWPNrJaZ1SNUHc2OMaZYnHPOObz44ov88MMPACxevJhly5ZxzDHHcMUVV5Cfn0+7du247bbbSnx9Xl4eq1atAmDEiBEcdthhnHjiidunqoYwRqBr16507NiRs88+mw0bNvDee+8xfvx4brjhBjp16sSCBQsYMGAATz/9NABvvPEGnTt3pn379gwcOHB7fHl5edx222106dKF9u3bM2fOnDL/Pk1XLZlg+fIweOuUU6BJkzCVw8SJYYK3558PvX+eey5M/JZNSQBiLBG4+xYzuwp4ldB99GF3n2lmg6P9D7j7bDN7BfgU2EboYjqjKu977bUwfXpVo99Zp05w992l72/cuDHdunXjlVdeoU+fPowdO5bzzz8fM2PEiBE0atSIrVu3csIJJ/Dpp5/SoUOHEs/z0UcfMXbsWD7++GO2bNlCly5dOPLIIwHo168fl112GQD//d//zd/+9jd+9atfceaZZ3LGGWdwzjnn7HSuTZs2MWDAAN544w0OPfRQLr74Yu6//36uvfZaAJo0acK0adO47777GDlyJA899FCpf5+mq5Z099lnYZWv77+H1q3hmmvCqN7u3SGaIDirxVrT5e4T3P1Qdz/E3UdE2x5w9wcSjrnL3du6+xHuXsbtNrUVVQ9BqBYqWg/gqaeeokuXLnTu3JmZM2fuVJ9f3JQpUzjrrLOoV68ee++9N2eeeeb2fTNmzODYY4+lffv2jBkzhpkzZ5YZz9y5c2nZsiWHHhqaXC655BImT568fX+/fv0AOPLII7dPVFead955h4suuggoebrqUaNG8d1331GrVi26du3KI488wvDhw/nss89o2LBhmecWidu6dWFRl4YNQ+Pv3Llhts+ePZUEimTcyOKyvrnHqW/fvgwZMoRp06axceNGunTpwqJFixg5ciRTp05lv/32Y8CAAaVOP13ESul7NmDA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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "loss_values = history_dict['loss']\n",
    "val_loss_values = history_dict['val_loss']\n",
    "epochs = range(1,len(loss_values)+1)\n",
    "plt.plot(epochs,loss_values,'bo',label='Training loss')\n",
    "plt.plot(epochs,val_loss_values,'b',label='Validation loss')\n",
    "plt.title('Training and validation loss')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Loss')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'acc'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-14-86abc9ef93b7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0macc_values\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mhistory_dict\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'acc'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[0mval_acc_values\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mhistory_dict\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'val_acc'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mepochs\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0macc_values\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'bo'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlabel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'Training acc'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mKeyError\u001b[0m: 'acc'"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 432x288 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.clf()\n",
    "acc_values = history_dict['acc']\n",
    "val_acc_values = history_dict['val_acc']\n",
    "\n",
    "plt.plot(epochs,acc_values,'bo',label='Training acc')\n",
    "plt.plot(epochs,val_acc_values,'b',label='Validation acc')\n",
    "plt.title('Training and validation accuracy')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Acc')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
